package com.ruoyi.business.service.impl;

import com.ruoyi.business.service.IProcessService;
import org.activiti.bpmn.model.BpmnModel;
import org.activiti.engine.HistoryService;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.TaskService;
import org.activiti.engine.history.HistoricActivityInstance;
import org.activiti.engine.history.HistoricProcessInstance;
import org.activiti.engine.history.HistoricTaskInstance;
import org.activiti.engine.repository.Deployment;
import org.activiti.engine.repository.ProcessDefinition;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Comment;
import org.activiti.engine.task.Task;
import org.activiti.image.ProcessDiagramGenerator;
import org.activiti.image.impl.DefaultProcessDiagramGenerator;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.net.PortUnreachableException;
import java.util.List;
import java.util.Map;
import java.util.zip.ZipInputStream;

@Service
public class ProcessServiceImpl implements IProcessService {

    @Autowired
    private RepositoryService repositoryService;

    @Autowired
    private RuntimeService runtimeService;

    @Autowired
    private TaskService taskService;

    @Autowired
    private HistoryService historyService;

    public  Deployment deploy(String filePath) throws FileNotFoundException {
        Deployment deploy = null;
        if (filePath.endsWith("zip")){
            ZipInputStream zipInputStream = new ZipInputStream(new FileInputStream(filePath));
            deploy = repositoryService.createDeployment()
                    .addInputStream(filePath, zipInputStream)
                    .deploy();
        }else if(filePath.endsWith("bpmn")){
            deploy = repositoryService.createDeployment()
                    .addInputStream(filePath, new FileInputStream(filePath))
                    .deploy();
        }
        return deploy;
    }

    @Override
    public ProcessDefinition selectProcessDefinitionByDeploymentId(String deploymentId) {
        return repositoryService.createProcessDefinitionQuery()
                .deploymentId(deploymentId)
                .singleResult();
    }
    @Override
    public InputStream getResourceAsStream(String deploymentId, String resourceName) {
        return repositoryService.getResourceAsStream(deploymentId,resourceName);
    }

    @Override
    public InputStream getProcessImage(String processDefinitionId,
                                       List<String> highLightedActivities,
                                       List<String> highLightedFlows) {
        BpmnModel model = repositoryService.getBpmnModel(processDefinitionId);
        ProcessDiagramGenerator generator = new DefaultProcessDiagramGenerator();
        //generateDiagram(流程模型,需要高亮的节点,需要高亮的线条,后面三个参数都表示是字体)
        InputStream inputStream = generator.generateDiagram(model, highLightedActivities, highLightedFlows,"宋体","宋体","宋体");
        return inputStream;
    }

    @Override
    public ProcessInstance deployByCarPackAgeAuditKey(String definitionKey, String packageKey, Map<String, Object> map) {
        return runtimeService.startProcessInstanceByKey(definitionKey,packageKey,map);
    }

    @Override
    public Task taskNameByProcessInstanceId(ProcessInstance processInstance) {
        return taskService.createTaskQuery().processInstanceId(processInstance.getId()).singleResult();
    }

    @Override
    public void addUser(Task task, Long userId) {
        taskService.addCandidateUser(task.getId(),userId.toString());
    }

    @Override
    public Task selectTeakByInstanceId(String instanceId) {
        return taskService.createTaskQuery().processInstanceId(instanceId).active().singleResult();
    }

    @Override
    public List<String> getActiceActivitiyids(String instanceId) {
        return runtimeService.getActiveActivityIds(instanceId);
    }

    @Override
    public ProcessInstance selectRunTimeServiceByiNstanceId(Long instanceId) {
        return runtimeService.createProcessInstanceQuery().processInstanceId(instanceId.toString()).singleResult();
    }

    @Override
    public void deleteByInstanceId(Long instanceId) {
        runtimeService.deleteProcessInstance(instanceId.toString(),"已被撤销");
    }

    @Override
    public long getTodoPageCount(String definitionKey,String candidateUser) {
        return taskService.createTaskQuery().processDefinitionKey(definitionKey)
                .taskCandidateUser(candidateUser)
                .count();
    }

    @Override
    public List<Task> selectTodoTaskList(String definitionKey, String candidateUser, int pageNum, int pageSize) {
        return taskService.createTaskQuery().processDefinitionKey(definitionKey).
                taskCandidateUser(candidateUser)
                .orderByTaskCreateTime()
                .desc()
                .listPage(pageNum,pageSize);
    }

    @Override
    public ProcessInstance getProcessInstanceById(String processInstanceId) {
        return runtimeService.createProcessInstanceQuery().processInstanceId(processInstanceId).singleResult();
    }

    @Override
    public Task getTaskByTaskId(String taskId) {
        return taskService.createTaskQuery().taskId(taskId).singleResult();
    }

    @Override
    public void claimAndComplateTask(Task task, String userId, boolean auditstatusBoolean, String commentStr) {
        //认领任务
        taskService.claim(task.getId(),userId);
        //设置流程变量
        taskService.setVariable(task.getId(),task.getTaskDefinitionKey(),auditstatusBoolean);
        //添加批注
        taskService.addComment(task.getId(),null,commentStr);
        //完成任务
        taskService.complete(task.getId());
    }

    /**
     * 设置流程变量
     * @param taskId
     * @param key
     * @param value
     */
    @Override
    public void setVariable(String taskId, String key, long value) {
        taskService.setVariable(taskId,key,value);
    }

    /**
     * 根据流程实例ID查询任务对象
     * @param processInstanceId
     * @return
     */
    @Override
    public Task getTaskByInstanceId(String processInstanceId) {
        return taskService.createTaskQuery().processInstanceId(processInstanceId).singleResult();
    }

    /**
     * 查询已办任务条数
     * @param definitionKey
     * @param candidateUser
     * @return
     */
    @Override
    public long selectDoneTaskCount(String definitionKey, String candidateUser) {
        return historyService.createHistoricTaskInstanceQuery()
                .processDefinitionKey(definitionKey)
                .taskAssignee(candidateUser)
                .finished()
                .count();
    }

    /**
     * 查询已办任务历史集合
     * @param definitionKey
     * @param candidateUser
     * @param beginIndex
     * @param pageSize
     * @return
     */
    @Override
    public List<HistoricTaskInstance> selectDoneList(String definitionKey, String candidateUser, Integer beginIndex, Integer pageSize) {
        return historyService.createHistoricTaskInstanceQuery()
                .processDefinitionKey(definitionKey)
                .taskAssignee(candidateUser)
                .finished()
                .orderByHistoricTaskInstanceEndTime()
                .desc()
                .listPage(beginIndex,pageSize);
    }

    @Override
    public HistoricProcessInstance getHistoricProcessInstanceById(String processInstanceId) {
        return historyService.createHistoricProcessInstanceQuery()
                .processInstanceId(processInstanceId)
                .singleResult();
    }

    /**
     * 根据流程实例ID查询历史流程实例
     * @param instanceId
     * @return
     */
    @Override
    public List<HistoricActivityInstance> selectHistoryTaskList(String instanceId) {
        return historyService.createHistoricActivityInstanceQuery()
                .processInstanceId(instanceId)
                .activityType("userTask")
                .finished()
                .orderByHistoricActivityInstanceStartTime()
                .desc()
                .list();
    }

    /**
     * 获取历史任务审核批注
     * @param taskId
     * @return
     */
    @Override
    public String getTaskComment(String taskId) {
        List<Comment> comments = taskService.getTaskComments(taskId, "comment");
        if(comments != null && comments.size() > 0){
            return comments.get(0).getFullMessage();
        }else {
            return "";
        }
    }
}
